/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.admin.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.springblade.common.utils.CommonUtil;
import org.springblade.common.utils.PoiExcelUtil;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.admin.dto.BuildingUserContractDTO;
import org.springblade.modules.admin.dto.BuildingUserDTO;
import org.springblade.modules.admin.dto.building.BuildingUserElevatorDTO;
import org.springblade.modules.admin.entity.*;
import org.springblade.modules.admin.service.*;
import org.springblade.modules.admin.vo.BuildingUserVO;
import org.springblade.modules.admin.vo.ElevatorDossierVO;
import org.springblade.modules.admin.vo.ProjectVO;
import org.springblade.modules.admin.vo.brand.BrandVersionUploadResultVo;
import org.springblade.modules.admin.vo.brand.BuildingUserUploadVo;
import org.springblade.modules.admin.vo.building.*;
import org.springblade.modules.admin.wrapper.BuildingUserWrapper;
import org.springblade.modules.system.entity.Region;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IRegionService;
import org.springblade.modules.system.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 项目使用单位 控制器
 *
 * @author ysq
 * @since 2023-08-09
 */
@RestController
@AllArgsConstructor
@RequestMapping("admin/buildinguser")
@Api(value = "项目使用单位", tags = "项目使用单位接口")
public class BuildingUserController extends BladeController {

	private final static String DOWN_EXCLE_ERROR_KEY = "brand_version:";
	private final IBuildingUserService buildingUserService;
	private final IPartsPriceLeaveService partsPriceLeaveService;
	private final ICustomTagService customTagService;
	private final RedisTemplate redisTemplate;
	private final IRegionService regionService;
	private final IBuildingUserContractService buildingUserContractJob;
	private final IUserService userService;
	private final IElevatorUpdateHistoryService elevatorUpdateHistoryService;

	@Autowired
	private RestTemplate restTemplate;

	/**
	 * 详情
	 */
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入buildingUser")
	public R<BuildingUserVO> detail(BuildingUser buildingUser) {
		BuildingUser detail = buildingUserService.getOne(Condition.getQueryWrapper(buildingUser));
		if (detail == null) {
			return R.data(null);
		}
		BuildingUserVO buildingUserVO = BuildingUserWrapper.build().entityVO(detail);
		PartsPriceLeave partsPriceLeave = partsPriceLeaveService.getById(detail.getPricesScaleId());
		if (partsPriceLeave != null) {
			buildingUserVO.setPricesScaleName(partsPriceLeave.getName());
		}
		CustomTag customTag = customTagService.getById(detail.getTagId());
		if (customTag != null) {
			buildingUserVO.setTagName(customTag.getName());
		}

		if (StrUtil.isNotEmpty(buildingUser.getBusinessLicenseNum())) {
			if (buildingUserVO.getId().equals(buildingUser.getId())) {
				return R.data(null);
			}
		}

		//客户负责人
		if (detail.getCustomerUserId() != null) {
			User user = userService.getById(detail.getCustomerUserId());
			if (user != null) {
				buildingUserVO.setCustomerUserName(user.getRealName());
			}
		}

		return R.data(buildingUserVO);
	}

	/**
	 * 新增
	 */
	@GetMapping("/isDelete")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "是否删除", notes = "buildingUser")
	public R<Boolean> isDelete(BuildingUser buildingUser) {
		Boolean boo = buildingUserService.isDelete(buildingUser.getId());
		return R.data(boo);
	}

	/**
	 * 自定义分页 项目使用单位
	 */
	@PostMapping("/page")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入buildingUser")
	public R<IPage<BuildingUserVO>> page(@RequestBody BuildingUserDTO buildingUserDTO) {
		if (buildingUserDTO.getSize() == null || buildingUserDTO.getSize() == 0) {
			buildingUserDTO.setSize(20);
		}
		IPage<BuildingUserVO> pages = buildingUserService.list(buildingUserDTO);
		return R.data(pages);
	}

	/**
	 * @return
	 * @Author lsay
	 * @Description {
	 * 列表
	 * }
	 * @Date 9:56 2023/8/14
	 * @Param
	 **/
	@GetMapping("/list")
	public R<List<BuildingUser>> list(BuildingUser buildingUser) {
		return R.data(buildingUserService.selectList(buildingUser));
	}

	/**
	 * 新增 项目使用单位
	 */
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增", notes = "传入buildingUser")
	public R save(@Valid @RequestBody BuildingUser buildingUser) {
		if (StrUtil.isNotEmpty(buildingUser.getBusinessLicenseNum())) {
			List<BuildingUser> buildingUsers = buildingUserService.list(
				Wrappers.<BuildingUser>lambdaQuery().eq(BuildingUser::getBuildingUserType, buildingUser.getBuildingUserType())
					.eq(BuildingUser::getBusinessLicenseNum, buildingUser.getBusinessLicenseNum()));
			if (buildingUsers.size() > 0) {
				throw new ServiceException("信用编号已经被使用");
			}
		}
		if (StrUtil.isNotEmpty(buildingUser.getName())) {
			List<BuildingUser> buildingUsers = buildingUserService.list(Wrappers.<BuildingUser>lambdaQuery().eq(BuildingUser::getName, buildingUser.getName()));
			if (buildingUsers.size() > 0) {
				throw new ServiceException("客户名称已经被使用");
			}
		}
		boolean save = buildingUserService.save(buildingUser);
		ElevatorUpdateHistory elevatorUpdateHistory = new ElevatorUpdateHistory();
		elevatorUpdateHistory.setWorkId(buildingUser.getId());
		elevatorUpdateHistory.setBeforeChange("创建客户");
		elevatorUpdateHistory.setAfterChange("创建客户信息");
		elevatorUpdateHistoryService.save(elevatorUpdateHistory);
		return R.data(buildingUser.getId());
	}

	/**
	 * 修改 项目使用单位
	 */
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入buildingUser")
	public R update(@Valid @RequestBody BuildingUser buildingUser) {
		if (StrUtil.isNotEmpty(buildingUser.getName())) {
			List<BuildingUser> buildingUsers = buildingUserService.list(Wrappers.<BuildingUser>lambdaQuery().eq(BuildingUser::getName, buildingUser.getName()).eq(BuildingUser::getBuildingUserType, buildingUser.getBuildingUserType()));
			buildingUsers = buildingUsers.stream().filter(o -> !o.getId().equals(buildingUser.getId())).collect(Collectors.toList());
			if (buildingUsers.size() > 0) {
				throw new ServiceException("客户名称已经被使用");
			}
		}
		return R.status(buildingUserService.updateById(buildingUser));
	}

	/**
	 * 删除 项目使用单位
	 */
	@PostMapping("/remove")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		return R.status(buildingUserService.deleteLogic(Func.toLongList(ids)));
	}


	@PostMapping("buildDingList")
	@ApiOperation(value = "项目列表")
	public R<IPage<ProjectVO>> buildDingList(@RequestBody BuildingUserDTO buildingUserDTO) {
		if (buildingUserDTO.getSize() == null || buildingUserDTO.getSize() == 0) {
			buildingUserDTO.setSize(500);
		}
		return R.data(buildingUserService.buildDingList(buildingUserDTO));
	}

	@PostMapping("buildDingList/v2")
	@ApiOperation(value = "项目列表-v2")
	public R<IPage<BuildingUserContract>> buildDingListV2(@RequestBody BuildingUserContractDTO buildingUserContractDTO) {
		return R.data(buildingUserContractJob.page(buildingUserContractDTO));
	}


	@PostMapping("elevatorList")
	public R<IPage<ElevatorDossierVO>> elevatorList(@RequestBody BuildingUserDTO buildingUserDTO) {
		if (buildingUserDTO.getSize() == null || buildingUserDTO.getSize() == 0) {
			buildingUserDTO.setSize(500);
		}
		if (StrUtil.isNotEmpty(buildingUserDTO.getBuildingAddress())) {
			buildingUserDTO.setBuildingName(buildingUserDTO.getBuildingAddress());
		}
		return R.data(buildingUserService.elevatorList(buildingUserDTO));
	}

	@PostMapping("elevatorList/v2")
	@ApiOperation("客户单位-电梯列表")
	public R<IPage<BuildingUserElevatorDetailVo>> elevatorListV2(@RequestBody BuildingUserElevatorDTO buildingUserElevatorDTO) {
		return R.data(buildingUserService.elevatorListV2(buildingUserElevatorDTO));
	}

	@GetMapping("elevator/status")
	@ApiOperation("客户单位-电梯合同统计")
	public R<BuildingUserElevatorVo> elevatorStatus(Long id, @RequestParam(defaultValue = "0") Integer timeType) {
		return R.data(buildingUserService.elevatorStatus(id, timeType));
	}


	@GetMapping("getContractGap")
	@ApiOperation("电梯断档问题列表")
	public R<List<BuildingUserContractGapVo>> getContractGap(Long elevatorId) {
		return R.data(buildingUserService.getContractGap(elevatorId));
	}

	@PostMapping("elevatorList/down/excel")
	@ApiOperation(value = "电梯列表下载")
	public void elevatorListDownExcel(HttpServletResponse response, @RequestBody BuildingUserDTO buildingUserDTO)
		throws IOException {
		buildingUserDTO.setSize(0);
		List<ElevatorDossierVO> records = buildingUserService.elevatorList(buildingUserDTO).getRecords();
		ExcelWriter excelWriter = null;
		ServletOutputStream outputStream = response.getOutputStream();
		try {
			List<List<String>> rows = new ArrayList<>();
			List<String> title = CollUtil.newArrayList("项目名称", "项目地址", "电梯梯号", "电梯年检类型", "设备注册代码", "电梯快速识别代码");
			rows.add(title);
			for (int i = 0; i < records.size(); i++) {
				ElevatorDossierVO elevatorDossierVO = records.get(i);
				List<String> row = new ArrayList<>();
				row.add(elevatorDossierVO.getBuildingName());
				row.add(elevatorDossierVO.getAddress());
				row.add(elevatorDossierVO.getElevatorAddress());
				row.add(elevatorDossierVO.getUseType() == 1 ? "非年审" : "年审");
				row.add(elevatorDossierVO.getPrivateNum());
				row.add(elevatorDossierVO.getElevatorNum());
				rows.add(row);
			}
			String fileName = DateUtil.format(new Date(), "yyyyMMddHHmmss") + ".xlsx";
			setResponseHeader(response, fileName);
			excelWriter = ExcelUtil.getBigWriter(rows.size());
			excelWriter.write(rows, true);
			excelWriter.flush(outputStream, true);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (excelWriter != null) {
				excelWriter.close();
			}
			outputStream.close();
		}
	}

	@GetMapping("catalogSearch")
	@ApiOperation(value = "关键字搜索公司列表")
	public R<List<Object>> catalogSearch(String keyword) {
		// 构建请求体
		JSONObject requestBody = new JSONObject();
		requestBody.put("keywords", keyword);
		requestBody.put("pageIndex", 1);
		requestBody.put("leadsFilter", "all");
		requestBody.put("pageSize", 50);
		requestBody.put("condition", "{}");
		requestBody.put("clickPath", "company-search");

		// 设置Cookie头
		String cookie = "Hm_lvt_84aae56c563e1fed9b8e6085bce83343=1750059462; HMACCOUNT=1D7F4A65AB75B548; PHPSESSID=3uqgle4h48f5r334i37ccg4qmq; Hm_lpvt_84aae56c563e1fed9b8e6085bce83343=1750061952";

		// 设置请求头
		org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
		headers.add("Cookie", cookie);
		headers.setContentType(org.springframework.http.MediaType.APPLICATION_JSON);

		// 创建请求实体
		org.springframework.http.HttpEntity<String> requestEntity = new org.springframework.http.HttpEntity<>(
			requestBody.toJSONString(), headers);

		// 发送POST请求
		ResponseEntity<String> responseEntity = restTemplate.postForEntity(
			"https://test1.javaw.icu/api/v1/company/company_search.php",
			requestEntity,
			String.class);

		// 解析响应
		JSONObject jsonResponse = JSON.parseObject(responseEntity.getBody());
		List<Object> records = jsonResponse.getJSONObject("data").getJSONObject("data").getJSONArray("records");
		return R.data(records);
	}


	@GetMapping("catalogDetailSearch")
	@ApiOperation(value = "id查找公司详情")
	public R<String> catalogDetailSearch(String id) {
		// 设置请求头
		org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
		String cookie = "Hm_lvt_84aae56c563e1fed9b8e6085bce83343=1750059462; HMACCOUNT=1D7F4A65AB75B548; PHPSESSID=3uqgle4h48f5r334i37ccg4qmq; Hm_lpvt_84aae56c563e1fed9b8e6085bce83343=1750061952";
		headers.add("Cookie", cookie);

		// 创建请求实体
		org.springframework.http.HttpEntity<?> requestEntity = new org.springframework.http.HttpEntity<>(headers);

		// 构建URL
		String url = "https://test1.javaw.icu/api/v1/company/company_detail/basic_info/company_detail.php?id=" + id;

		// 发送GET请求
		org.springframework.http.ResponseEntity<String> responseEntity = restTemplate.exchange(
			url,
			org.springframework.http.HttpMethod.GET,
			requestEntity,
			String.class
		);

		// 解析响应
		String response = responseEntity.getBody();
		JSONObject jsonResponse = JSON.parseObject(response);

		// 提取并返回creditNumber
		return R.data(jsonResponse.getJSONObject("data").getJSONObject("data").getString("creditNumber"));
	}


	/**
	 * 获取项目客户单位的
	 *
	 * @return
	 */
	@GetMapping("getBuildingUserStatus")
	@ApiOperation("客户单位统计信息")
	public R<BuildingUserStatusVo> getBuildingUserStatus(Long id) {
		return R.data(buildingUserService.getBuildingUserStatus(id));
	}


	@PostMapping("page/v2")
	@ApiOperation("客户单位分页v2版本")
	public R<IPage<BuildingUserPageVo>> pageV2(@RequestBody BuildingUserDTO buildingUserDTO) {
		return R.data(buildingUserService.pageV2(buildingUserDTO));
	}


	@PostMapping("page/v2/down")
	@ApiOperation("客户单位分页v2版本")
	public void downExcelPageV2(HttpServletResponse response, @RequestBody BuildingUserDTO buildingUserDTO) throws IOException {
		ExcelWriter excelWriter = null;
		buildingUserDTO.setSize(0);
		List<BuildingUserPageVo> records = buildingUserService.pageV2(buildingUserDTO).getRecords();
		ServletOutputStream outputStream = response.getOutputStream();
		try {
			List<List<String>> rows = new ArrayList<>();
			List<String> title = CollUtil.newArrayList("合作分类", "客户名称", "客户类型", "合作项目数", "合作电梯数", "问题项目数", "问题电梯数", "项目总数", "电梯总数", "客服负责人");
			rows.add(title);
			for (int i = 0; i < records.size(); i++) {
				BuildingUserPageVo buildingUserPageVo = records.get(i);
				List<String> row = new ArrayList<>();
				if (buildingUserPageVo.getType() == 0) {
					row.add(Convert.toStr("丢失客户"));
				} else if (buildingUserPageVo.getType() == 1) {
					row.add(Convert.toStr("合作客户"));
				} else {
					row.add("--");
				}
				row.add(Convert.toStr(buildingUserPageVo.getName()));
				row.add(Convert.toStr(buildingUserPageVo.getUserType() == 1 ? "个人" : "公司"));
				row.add(Convert.toStr(buildingUserPageVo.getInTimeBuildingCounts()));
				row.add(Convert.toStr(buildingUserPageVo.getInTimeEleCounts()));
				row.add(Convert.toStr(buildingUserPageVo.getQuestionBuildingCounts()));
				row.add(Convert.toStr(buildingUserPageVo.getQuestionEleCounts()));
				row.add(Convert.toStr(buildingUserPageVo.getAllBuildingCounts()));
				row.add(Convert.toStr(buildingUserPageVo.getAllEleCounts()));
				row.add(Convert.toStr(buildingUserPageVo.getCustomerUserName()));
				rows.add(row);
			}
			String fileName = DateUtil.format(new Date(), "yyyyMMddHHmmss") + ".xlsx";
			setResponseHeader(response, fileName);
			excelWriter = ExcelUtil.getBigWriter(rows.size());
			excelWriter.write(rows, true);
			excelWriter.flush(outputStream, true);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (excelWriter != null) {
				excelWriter.close();
			}
			outputStream.close();
		}
	}


	@ApiOperation("excel下载错误信息")
	@PostMapping("down/error/excel")
	public void downExcel(HttpServletResponse response,
						  @RequestBody BrandVersionUploadResultVo brandVersionUploadResultVo) throws IOException {
		final String toStr = Convert.toStr(redisTemplate.opsForValue().get(brandVersionUploadResultVo.getDownExcelKey()));
		List<BuildingUserUploadVo> buildingUserUploadVos = JSON.parseArray(toStr, BuildingUserUploadVo.class);
		XSSFWorkbook workbook = this.initExcelTemplate(brandVersionUploadResultVo.getBuildingUserType());
		XSSFSheet sheet = workbook.getSheetAt(0);
		for (int i = 0; i < buildingUserUploadVos.size(); i++) {
			BuildingUserUploadVo brandVersionUploadVo = buildingUserUploadVos.get(i);
			XSSFRow row = sheet.createRow(i + 2);
			row.setHeightInPoints(20);
			XSSFCell cell0 = row.createCell(0);
			cell0.setCellValue(Convert.toStr(brandVersionUploadVo.getName()));

			XSSFCell cell1 = row.createCell(1);
			cell1.setCellValue(Convert.toStr(brandVersionUploadVo.getUserTypeName()));

			XSSFCell cell2 = row.createCell(2);
			cell2.setCellValue(Convert.toStr(brandVersionUploadVo.getBusinessLicenseNum()));

			XSSFCell cell3 = row.createCell(3);
			cell3.setCellValue(Convert.toStr(brandVersionUploadVo.getContactUserName()));

			XSSFCell cell4 = row.createCell(4);
			cell4.setCellValue(Convert.toStr(brandVersionUploadVo.getContactUserPhone()));

			XSSFCell cell5 = row.createCell(5);
			cell5.setCellValue(Convert.toStr(brandVersionUploadVo.getTagName()));

			XSSFCell cell6 = row.createCell(6);
			cell6.setCellValue(Convert.toStr(brandVersionUploadVo.getPricesScaleName()));

			XSSFCell cell7 = row.createCell(7);
			cell7.setCellValue(Convert.toStr(brandVersionUploadVo.getProvinceName()));

			XSSFCell cell8 = row.createCell(8);
			cell8.setCellValue(Convert.toStr(brandVersionUploadVo.getCityName()));

			XSSFCell cell9 = row.createCell(9);
			cell9.setCellValue(Convert.toStr(brandVersionUploadVo.getAdName()));

			XSSFCell cell10 = row.createCell(10);
			cell10.setCellValue(Convert.toStr(brandVersionUploadVo.getAddress()));

			XSSFCell cell11 = row.createCell(11);
			cell11.setCellValue(Convert.toStr(brandVersionUploadVo.getBankName()));

			XSSFCell cell12 = row.createCell(12);
			cell12.setCellValue(Convert.toStr(brandVersionUploadVo.getBankAccount()));

			XSSFCell cell13 = row.createCell(13);
			cell13.setCellValue(Convert.toStr(brandVersionUploadVo.getInvoiceTitle()));

			XSSFCell cell14 = row.createCell(14);
			cell14.setCellValue(Convert.toStr(brandVersionUploadVo.getInvoiceNum()));

			XSSFCell cell15 = row.createCell(15);
			cell15.setCellValue(Convert.toStr(brandVersionUploadVo.getTaxType()));

			XSSFCell cell16 = row.createCell(16);
			cell16.setCellValue(Convert.toStr(brandVersionUploadVo.getTaxRate()));

			XSSFCell cell17 = row.createCell(17);
			cell17.setCellValue(Convert.toStr(brandVersionUploadVo.getTaxEmail()));

		}
		String fileName = "error-" + DateUtil.format(new Date(), "yyyyMMddHHmmss") + ".xlsx";
		ServletOutputStream outputStream = null;
		try {
			outputStream = response.getOutputStream();
			CommonUtil.setResponseHeader(response, fileName);
			workbook.write(outputStream);
			outputStream.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (workbook != null) {
					workbook.close();
				}
				outputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	@ApiOperation("excel上传")
	@PostMapping("upload/excel")
	public R<BrandVersionUploadResultVo> uploadExcel(@RequestParam(defaultValue = "2") Integer buildingUserType,
													 @RequestParam("file") MultipartFile file) throws IOException {

		BrandVersionUploadResultVo brandVersionUploadResultVo = new BrandVersionUploadResultVo();
		if (file.isEmpty()) {
			return R.fail("上传文件不能为空");
		}
		Workbook wb = null;
		try {
			wb = WorkbookFactory.create(file.getInputStream());
			List<Map<String, Object>> readAll = PoiExcelUtil.readExcel(wb, 0, 1, 1, 0);
		} catch (Exception e) {
			return R.fail("请使用正确的使用单位模板");
		}
		List<BuildingUserUploadVo> errorList = new ArrayList<>(100);
		List<Map<String, Object>> readAll = PoiExcelUtil.readExcel(wb, 0, 1, 1, 0);
		Map<String, Object> headerMap = readAll.get(0);
		String nameHeader = Convert.toStr(headerMap.get("使用单位名称"), "");
		if (StrUtil.isEmpty(nameHeader)) {
			nameHeader = Convert.toStr(headerMap.get("客户单位名称"), "");
		}
		String userTypeNameHeader = Convert.toStr(headerMap.get("单位类型"), "");
		String businessLicenseNumHeader = Convert.toStr(headerMap.get("统一社会信用代码"), "");
		if (nameHeader == null || userTypeNameHeader == null || businessLicenseNumHeader == null) {
			brandVersionUploadResultVo.setIsTemplate(false);
			return R.data(brandVersionUploadResultVo);
		}
		if (buildingUserType == 2) {
			if (!nameHeader.equals("使用单位名称") || !userTypeNameHeader.equals("单位类型")
				|| !businessLicenseNumHeader.equals("统一社会信用代码")) {
				brandVersionUploadResultVo.setIsTemplate(false);
				return R.data(brandVersionUploadResultVo);
			}
		} else {
			if (!nameHeader.equals("客户单位名称") || !userTypeNameHeader.equals("单位类型")
				|| !businessLicenseNumHeader.equals("统一社会信用代码")) {
				brandVersionUploadResultVo.setIsTemplate(false);
				return R.data(brandVersionUploadResultVo);
			}
		}
		readAll.remove(0);
		brandVersionUploadResultVo.setAllCounts(readAll.size());

		if (readAll.size() == 0) {
			return R.fail("导入文件数据不能为空");
		}

		for (int i = 0; i < readAll.size(); i++) {
			Map<String, Object> objects = readAll.get(i);
			// 使用单位
			String name1 = Convert.toStr(objects.get("使用单位名称"), "");
			String name2 = Convert.toStr(objects.get("客户单位名称"), "");
			// 单位类型
			String userTypeName = Convert.toStr(objects.get("单位类型"), "");
			String businessLicenseNum = Convert.toStr(objects.get("统一社会信用代码"), "");
			String contactUserName1 = Convert.toStr(objects.get("使用单位联系人"), "");
			String contactUserName2 = Convert.toStr(objects.get("客户单位联系人"), "");
			String contactUserPhone = Convert.toStr(objects.get("联系电话"), "");
			String tagName = Convert.toStr(objects.get("客户标签"), "");
			String pricesScaleName = Convert.toStr(objects.get("价格等级"), "");
			String provinceName = Convert.toStr(objects.get("地址(省/自治区/直辖市)"), "");
			String cityName = Convert.toStr(objects.get("地址(市)"), "");
			String adName = Convert.toStr(objects.get("地址(县/区)"), "");
			String address = Convert.toStr(objects.get("地址(详细地址)"), "");
			String bankName = Convert.toStr(objects.get("开户银行"), "");
			String bankAccount = Convert.toStr(objects.get("银行账户"), "");
			String invoiceTitle = Convert.toStr(objects.get("发票抬头"), "");
			String invoiceNum = Convert.toStr(objects.get("开票税号"), "");
			String taxType = Convert.toStr(objects.get("税种"), "");
			String taxRate = Convert.toStr(objects.get("增值税税率%"), "");
			String taxEmail = Convert.toStr(objects.get("收票邮箱"), "");
			String openPhone = Convert.toStr(objects.get("开户账号"), "");

			BuildingUser buildingUser = new BuildingUser();
			buildingUser.setName(StrUtil.isEmpty(name1) ? name2 : name1);
			buildingUser.setUserType(userTypeName.equals("个人") ? 1 : 2);
			buildingUser.setBusinessLicenseNum(businessLicenseNum);
			BuildingUserUploadVo buildingUserUploadVo = new BuildingUserUploadVo();
			buildingUserUploadVo.setNum("第" + (i + 1) + "条数据出错");
			buildingUserUploadVo.setUserTypeName(userTypeName);
			buildingUserUploadVo.setTagName(tagName);
			buildingUserUploadVo.setPricesScaleName(pricesScaleName);
			buildingUser.setAddress(address);
			buildingUser.setContactUserName(StrUtil.isEmpty(contactUserName1) ? contactUserName2 : contactUserName1);
			buildingUser.setContactUserPhone(contactUserPhone);
			buildingUser.setBankName(bankName);
			buildingUser.setBankAccount(bankAccount);
			buildingUser.setInvoiceTitle(invoiceTitle);
			buildingUser.setInvoiceNum(invoiceNum);
			buildingUser.setTaxType(taxType);
			buildingUser.setTaxRate(Convert.toInt(taxRate, 0));
			buildingUser.setTaxEmail(taxEmail);
			buildingUser.setAdName(adName);
			buildingUser.setBuildingUserType(buildingUserType);
			buildingUser.setProvinceName(provinceName);
			buildingUser.setCityName(cityName);
			buildingUser.setOpenPhone(openPhone);
			BeanUtil.copyProperties(buildingUser, buildingUserUploadVo);

			if (StrUtil.isEmpty(buildingUser.getName())) {
				buildingUserUploadVo.setErrorBody("单位名称不能为空");
				errorList.add(buildingUserUploadVo);
				continue;
			}
			if (StrUtil.isEmpty(businessLicenseNum)) {
				buildingUserUploadVo.setErrorBody("社会信任代码不能为空");
				errorList.add(buildingUserUploadVo);
				continue;
			}

			if (StrUtil.isEmpty(userTypeName)) {
				buildingUserUploadVo.setErrorBody("单位类型不能为空");
				errorList.add(buildingUserUploadVo);
				continue;
			}
			if (StrUtil.isEmpty(pricesScaleName)) {
				buildingUserUploadVo.setErrorBody("价格等级不能为空");
				errorList.add(buildingUserUploadVo);
				continue;
			}
			if (StrUtil.isEmpty(tagName)) {
				buildingUserUploadVo.setErrorBody("客戶等级不能为空");
				errorList.add(buildingUserUploadVo);
				continue;
			}

			final List<BuildingUser> userList = buildingUserService
				.list(Wrappers.<BuildingUser>lambdaQuery().eq(BuildingUser::getBusinessLicenseNum, businessLicenseNum));
			if (userList.size() > 0) {
				buildingUserUploadVo.setErrorBody("社会信用代码重复");
				errorList.add(buildingUserUploadVo);
				continue;
			}

			List<PartsPriceLeave> priceLeaves = partsPriceLeaveService
				.list(Wrappers.<PartsPriceLeave>lambdaQuery().eq(PartsPriceLeave::getName, pricesScaleName));
			if (priceLeaves.size() == 0) {
				buildingUserUploadVo.setErrorBody("价格等级不存在");
				errorList.add(buildingUserUploadVo);
				continue;
			}
			List<CustomTag> customTags = customTagService
				.list(Wrappers.<CustomTag>lambdaQuery().eq(CustomTag::getName, tagName));
			if (customTags.size() == 0) {
				buildingUserUploadVo.setErrorBody("客户等级不存在");
				errorList.add(buildingUserUploadVo);
				continue;
			}

			List<Region> provinceModel = regionService
				.list(Wrappers.<Region>lambdaQuery().eq(Region::getProvinceName, provinceName));
			if (provinceModel.size() > 0) {
				buildingUser.setProvinceCode(provinceModel.get(0).getProvinceCode());
			}
			List<Region> cityModel = regionService.list(Wrappers.<Region>lambdaQuery().eq(Region::getCityName, cityName));
			if (cityModel.size() > 0) {
				buildingUser.setCityCode(cityModel.get(0).getCityCode());
			}
			List<Region> adModel = regionService.list(Wrappers.<Region>lambdaQuery().eq(Region::getDistrictName, adName));
			if (adModel != null && adModel.size() > 0) {
				buildingUser.setAdCode(adModel.get(0).getDistrictCode());
			}

			buildingUser.setTagId(customTags.get(0).getId());
			buildingUser.setPricesScaleId(priceLeaves.get(0).getId());
			buildingUserService.save(buildingUser);
		}
		brandVersionUploadResultVo.setFailCounts(errorList.size());
		brandVersionUploadResultVo.setSucceedCounts(readAll.size() - errorList.size());
		brandVersionUploadResultVo.setFileName(file.getOriginalFilename());
		brandVersionUploadResultVo.setFailBuildingUserList(errorList);
		if (errorList.size() > 0) {
			brandVersionUploadResultVo.setResultDesc("共导入" + readAll.size() + "条数据,通过" + (readAll.size() - errorList.size())
				+ "条,失败" + errorList.size() + "条。失败原因如下");
		} else {
			brandVersionUploadResultVo.setResultDesc("共成功导入" + readAll.size() + "条数据");
		}
		String key = DOWN_EXCLE_ERROR_KEY + System.currentTimeMillis();
		brandVersionUploadResultVo.setDownExcelKey(key);
		if (errorList.size() > 0) {
			redisTemplate.opsForValue().set(key, JSON.toJSON(errorList), 30, TimeUnit.MINUTES);
		}
		return R.data(brandVersionUploadResultVo);

	}


	@PostMapping("down/excel")
	@ApiOperation(value = "使用单位下载")
	public void downExcel(HttpServletResponse response, @RequestBody BuildingUserDTO buildingUserDTO) throws IOException {
		ExcelWriter excelWriter = null;
		buildingUserDTO.setSize(0);
		List<BuildingUserVO> records = buildingUserService.list(buildingUserDTO).getRecords();
		ServletOutputStream outputStream = response.getOutputStream();
		try {
			List<List<String>> rows = new ArrayList<>();
			List<String> title;
			if (buildingUserDTO.getBuildingUserType() == 2) {
				title = CollUtil.newArrayList("使用单位名称", "单位类型", "统一社会信用代码", "使用单位联系人", "联系电话", "项目数", "电梯数", "客户标签", "价格等级",
					"地址(省/自治区/直辖市)", "地址(市)", "地址(县/区)", "地址(详细地址)", "开户银行", "开户电话", "银行账户", "发票抬头", "开票税号", "增值税税率%", "税种",
					"收票邮箱");
			} else {
				title = CollUtil.newArrayList("客戶单位名称", "单位类型", "统一社会信用代码", "客戶单位联系人", "联系电话", "项目数", "电梯数", "客户标签", "价格等级",
					"地址(省/自治区/直辖市)", "地址(市)", "地址(县/区)", "地址(详细地址)", "开户银行", "开户电话", "银行账户", "发票抬头", "开票税号", "增值税税率%", "税种",
					"收票邮箱");
			}
			rows.add(title);
			for (int i = 0; i < records.size(); i++) {
				BuildingUserVO buildingUserVO = records.get(i);
				List<String> row = new ArrayList<>();
				row.add(Convert.toStr(buildingUserVO.getName()));
				row.add(Convert.toStr(buildingUserVO.getUserType() == 1 ? "个人" : "公司"));
				row.add(Convert.toStr(buildingUserVO.getBusinessLicenseNum(), ""));
				row.add(Convert.toStr(buildingUserVO.getContactUserName(), ""));
				row.add(Convert.toStr(buildingUserVO.getContactUserPhone(), ""));
				if (buildingUserVO.getBuildingIds() != null) {
					row.add(Convert.toStr(buildingUserVO.getBuildingIds().size(), ""));
				} else {
					row.add(Convert.toStr(""));
				}
				if (buildingUserVO.getElevatorIds() != null) {
					row.add(Convert.toStr(buildingUserVO.getElevatorIds().size(), ""));
				} else {
					row.add("");
				}
				row.add(Convert.toStr(buildingUserVO.getTagName()));
				row.add(Convert.toStr(buildingUserVO.getPricesScaleName(), ""));
				row.add(Convert.toStr(buildingUserVO.getProvinceName(), ""));
				row.add(Convert.toStr(buildingUserVO.getCityName(), ""));
				row.add(Convert.toStr(buildingUserVO.getAdName(), ""));
				row.add(Convert.toStr(buildingUserVO.getAddress(), ""));
				row.add(Convert.toStr(buildingUserVO.getBankName(), ""));
				row.add(Convert.toStr(buildingUserVO.getOpenPhone(), ""));
				row.add(Convert.toStr(buildingUserVO.getBankAccount(), ""));
				row.add(Convert.toStr(buildingUserVO.getInvoiceNum(), ""));
				row.add(Convert.toStr(buildingUserVO.getInvoiceTitle(), ""));
				row.add(Convert.toStr(buildingUserVO.getTaxRate(), ""));
				row.add(Convert.toStr(buildingUserVO.getTaxType(), ""));
				row.add(Convert.toStr(buildingUserVO.getTaxEmail(), ""));
				rows.add(row);
			}
			String fileName = DateUtil.format(new Date(), "yyyyMMddHHmmss") + ".xlsx";
			setResponseHeader(response, fileName);
			excelWriter = ExcelUtil.getBigWriter(rows.size());
			excelWriter.write(rows, true);
			excelWriter.flush(outputStream, true);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (excelWriter != null) {
				excelWriter.close();
			}
			outputStream.close();
		}
	}


	@GetMapping("test")
	@ApiOperation("测试")
	public void test() {
		buildingUserContractJob.buildingUserContractJob();
	}


	/**
	 * 功能描述: 发送响应流方法
	 */
	private void setResponseHeader(HttpServletResponse response, String fileName) {
		try {
			try {
				fileName = new String(fileName.getBytes(), "ISO8859-1");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			response.setContentType("application/octet-stream;charset=ISO8859-1");
			response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
			response.addHeader("Pargam", "no-cache");
			response.addHeader("Cache-Control", "no-cache");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 初始化excel模板
	 *
	 * @return
	 */
	private XSSFWorkbook initExcelTemplate(Integer buildingUserType) {
		XSSFWorkbook workbook = null;
		try {
			// 读取源文件
			ClassPathResource resource;
			if (buildingUserType == 2) {
				resource = new ClassPathResource("templates/building_user.xlsx");
			} else {
				resource = new ClassPathResource("templates/building_user_v2.xlsx");
			}
			workbook = new XSSFWorkbook(resource.getInputStream());
		} catch (IOException e) {
			e.printStackTrace();
			throw new ServiceException("使用单位模板文件异常！");
		}

		// 进行模板的克隆（接下来的操作都是针对克隆后的sheet）
		XSSFSheet sheet = workbook.cloneSheet(0);
		// 行数
		final int maxRow = 1000;
		// 清空内容
		this.removeRow(sheet, 2, maxRow);

		// 自定义样式
		XSSFCellStyle style = workbook.createCellStyle();
		// 自定义颜色对象
		XSSFColor color = new XSSFColor();
		int rgb = CommonUtil.getIntFromColor(217, 217, 217);
		color.setRGB(CommonUtil.intToByteArray(rgb));
		style.setFillForegroundColor(color);
		// 前景填充模式
		style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		// 创建一个居中格式
		style.setAlignment(HorizontalAlignment.CENTER);
		// 垂直居中
		style.setVerticalAlignment(VerticalAlignment.CENTER);
		// 新建一个字体
		XSSFFont whiteFont = workbook.createFont();
		whiteFont.setColor(IndexedColors.BLACK.getIndex());
		whiteFont.setFontHeightInPoints((short) 12);
		style.setFont(whiteFont);
		return workbook;
	}

	/**
	 * 从某行开始，清除固定行（清除样式）
	 *
	 * @param sheet
	 * @param startRow
	 * @param endRow
	 */
	private void removeRow(XSSFSheet sheet, int startRow, int endRow) {
		for (int j = endRow; j >= startRow; j--) {
			if (sheet.getRow(j) == null) {
				continue;
			}
			sheet.removeRow(sheet.getRow(j));
		}
	}
}
